﻿#pragma once

#if !defined(__MINGW32__)
#define __MINGW32__
#endif

#if defined(_MSC_VER)
#define strcasecmp _stricmp
#endif

#include <mp4v2/mp4v2.h>
#include <string>

struct Mp4DecoderData
{
	~Mp4DecoderData() 
	{
		if (sampleData)
		{
			MP4Free(sampleData);
			sampleData = nullptr;
		}
	}

	uint8_t*        sampleData = nullptr;   // 帧数据指针
	uint32_t        sampleSize = 0;         // 帧数据长度
	MP4Timestamp    startTime = 0;          // 开始时间
	MP4Duration     duration = 0;           // 持续时间
	MP4Duration     offset = 0;             // 偏移时间
	bool            isKeyFrame = false;     // 是否关键帧
	uint32_t        timescale = 0;
	uint64_t        msectime = 0;
};

class Mp4Decoder
{
public:
	Mp4Decoder();
	~Mp4Decoder();

	/** 打开解码器 */
	bool open(const std::string& filePathName);

	/** 关闭解码器 */
	void close();

	/** 读取一帧视频 */
	bool readVideo(Mp4DecoderData* data);

	/** 读取一帧音频 */
	bool readAudio(Mp4DecoderData* data);

private:
	/** 文件句柄 */
	MP4FileHandle _mp4FileHandle;

	/** 总毫秒数 */
	uint32_t _mp4Duration;

	MP4TrackId _tidVideo = MP4_INVALID_TRACK_ID; // 视频轨道编号
	MP4TrackId _tidAudio = MP4_INVALID_TRACK_ID; // 音频轨道编号

	std::string _stringSPS, _stringPPS, _stringAES;
	int         _audio_channel_num = 0;
	int         _audio_type = 0;
	uint32_t    _audio_time_scale = 0;
	uint32_t    _video_time_scale = 0;

	const char* _video_name;
	char* _audioInfo;
	const char* _audio_name;

	bool videoComplete = false;
	bool audioComplete = false;

	uint32_t videoSampleIndex = 1;
	uint32_t audioSampleIndex = 1;

	/** 解析MP4音视频数据帧 */
	bool parse(MP4FileHandle inFile);

	/** 抽取一帧音频或视频数据帧 */
	bool readOneFrame(MP4FileHandle inFile, MP4TrackId tid, uint32_t sid, Mp4DecoderData* data);
};